package controllers;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import play.db.DB;
import play.mvc.Controller;
import play.mvc.Result;

public class FeatureExtraction extends Controller {
	
public static JsonNode getfromDB(String link){
		
		String json="";
		 try {
		        URL u = new URL(link);
		        HttpURLConnection c = (HttpURLConnection) u.openConnection();
		        c.setRequestMethod("GET");
		        c.setRequestProperty("Content-length", "0");
		        c.setUseCaches(false);
		        c.setAllowUserInteraction(false);
		        c.connect();
		        int status = c.getResponseCode();

		        switch (status) {
		            case 200:
		            case 201:
		                BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));
		                StringBuilder sb = new StringBuilder();
		                String line;
		                while ((line = br.readLine()) != null) {
		                    sb.append(line+"\n");
		                }
		                br.close();
		                json= sb.toString();
		        }

		    } catch (MalformedURLException ex) {
		        
		    } catch (IOException ex) {
		        
		    }
		 ObjectMapper mapper = new ObjectMapper();
		 JsonNode jsonObj=null;

		try {
			jsonObj = mapper.readTree(json);
		} catch (JsonProcessingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		 
		return jsonObj;
		
	}
	

	
	public static String getMovieLegth(String id){
		
		String link="https://api.themoviedb.org/3/movie/"+id+"?api_key=87e2038b0b713a173ad4a94537fe4dd8";
		JsonNode result=getfromDB(link);
		String length = result.findPath("runtime").asText();
		return length;
		
	}
	
	public static String IsForAdults(String id){
		
		String link="https://api.themoviedb.org/3/movie/"+id+"?api_key=87e2038b0b713a173ad4a94537fe4dd8";
		JsonNode result=getfromDB(link);
		String adult = result.findPath("adult").asText();
		return adult;
		
	}
	
public static String getMovieBudget(String id){
		
		String link="https://api.themoviedb.org/3/movie/"+id+"?api_key=87e2038b0b713a173ad4a94537fe4dd8";
		JsonNode result=getfromDB(link);
		String budget = result.findPath("budget").asText();
		return budget;
		
	}

public static ArrayList<String> getMovieGenres(String id){
	
	String link="https://api.themoviedb.org/3/movie/"+id+"?api_key=87e2038b0b713a173ad4a94537fe4dd8";
	JsonNode result=getfromDB(link);
	Iterator<JsonNode> iter=result.findPath("genres").elements();
	ArrayList<String> genres=new ArrayList<>();
	while(iter.hasNext()){
		genres.add(iter.next().findPath("name").asText());

	}

	return genres;
	
}

public static String getPopularity(String id){
	
	String link="https://api.themoviedb.org/3/movie/"+id+"?api_key=87e2038b0b713a173ad4a94537fe4dd8";
	JsonNode result=getfromDB(link);
	String popularity = result.findPath("popularity").asText();
	return popularity;
	
}
	
public static String getVoteAvg(String id){
	
	String link="https://api.themoviedb.org/3/movie/"+id+"?api_key=87e2038b0b713a173ad4a94537fe4dd8";
	JsonNode result=getfromDB(link);
	String vote = result.findPath("vote_average").asText();
	return vote;
	
}

public static String getRevenue(String id){
	
	String link="https://api.themoviedb.org/3/movie/"+id+"?api_key=87e2038b0b713a173ad4a94537fe4dd8";
	JsonNode result=getfromDB(link);
	String rev = result.findPath("revenue").asText();
	return rev;
	
}

public static String getReleaseDate(String id){
	
	String link="https://api.themoviedb.org/3/movie/"+id+"?api_key=87e2038b0b713a173ad4a94537fe4dd8";
	JsonNode result=getfromDB(link);
	String rel = result.findPath("release_date").asText();
	return rel;
	
}
	
	
public static ArrayList<String> getProductionCompanies(String id){
	
	String link="https://api.themoviedb.org/3/movie/"+id+"?api_key=87e2038b0b713a173ad4a94537fe4dd8";
	JsonNode result=getfromDB(link);
	Iterator<JsonNode> iter=result.findPath("production_companies").elements();
	ArrayList<String> comp=new ArrayList<>();
	while(iter.hasNext()){
		comp.add(iter.next().findPath("name").asText());

	}

	return comp;
	
}

public static ArrayList<String> getProductionCountries(String id){
	
	String link="https://api.themoviedb.org/3/movie/"+id+"?api_key=87e2038b0b713a173ad4a94537fe4dd8";
	JsonNode result=getfromDB(link);
	Iterator<JsonNode> iter=result.findPath("production_countries").elements();
	ArrayList<String> countries=new ArrayList<>();
	while(iter.hasNext()){
		countries.add(iter.next().findPath("name").asText());

	}

	return countries;
	
}

public static String getCredits(String id){
	
	String link="https://api.themoviedb.org/3/movie/"+id+"/credits?api_key=87e2038b0b713a173ad4a94537fe4dd8";
	JsonNode result=getfromDB(link);
	System.out.println("resrserser "+result);
	//String rev = result.findPath("revenue").asText();
	return link;
	
}
	

public static ArrayList<String> getCast(String id){
	
	String link="https://api.themoviedb.org/3/movie/"+id+"/credits?api_key=87e2038b0b713a173ad4a94537fe4dd8";
	JsonNode result=getfromDB(link);
	Iterator<JsonNode> iter=result.findPath("cast").elements();
	ArrayList<String> cast=new ArrayList<>();
	while(iter.hasNext()){
		cast.add(iter.next().findPath("name").asText());

	}
	return cast;
	
}

public static String getDirector(String id){
	
	String link="https://api.themoviedb.org/3/movie/"+id+"/credits?api_key=87e2038b0b713a173ad4a94537fe4dd8";
	JsonNode result=getfromDB(link);
	Iterator<JsonNode> iter=result.findPath("crew").elements();
	//List<String> cast=new ArrayList<>();
	while(iter.hasNext()){
		JsonNode node=iter.next();
		if(node.findPath("job").asText().equals("Director"));
		return node.findPath("name").asText();

	
	}
	return "";
	
}

public static String getMovieDBID(int db_index){
	Connection c = null;
	Statement st = null;
	ResultSet rs=null;
	try{
		c = DB.getConnection();
		//st = c.createStatement();		
		//insert length of movie	
		
    	rs = c.createStatement().executeQuery( "SELECT TMDBID FROM movie WHERE ID ="+db_index+";" );
	}
	catch ( Exception exc) {
	      System.err.println("Database error in obtaining movie id. "+exc.toString());
	      System.exit(0);
	    }	
	
	String res="";

	try {
		rs.next();
		res = ""+rs.getString("TMDBID");
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	try {
		c.close();
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	return res;
	
}

public static void fillDatabase(){
	
	int movieCount=200;
	Connection c = null;
	Statement st = null;
		
	try{
		c = DB.getConnection();
		st = c.createStatement();
		int feature_id=1;
		String [] moviedbids=new String[movieCount];
		//insert length of movie	
		st.executeUpdate("INSERT INTO feature (Name) VALUES ('Length of the movie');");	
		st.close();	
		for(int i=1;i<=movieCount;i++){	
		String tmdbid=getMovieDBID(i);		
		moviedbids[i-1]=tmdbid;
		Thread.sleep(500);		
		st = c.createStatement();
		String length=getMovieLegth(tmdbid);
		st.executeUpdate("INSERT INTO data (MovieID, FeatureID, Value) VALUES ("+i+","+feature_id+","+length+");");	
		st.close();
		}
		
		
		String [] actors={"Brad Pitt", "Clint Eastwood","Harrison Ford","Marylin Monroe","Audrey Hepburn"};
		String [] directors={"Quentin Tarantino","Woody Allen","Steven Spielberg"};
		String [] genres={"Western","Drama","Comedy","Action","Crime","Horror"};
		String [] production_country={"United States of America","United Kingdom","France","Japan"};
		
		//get actors
		
		//insert is actor in movie
		for(int m=0;m<actors.length;m++){
			feature_id++;
			st = c.createStatement();
				st.executeUpdate("INSERT INTO feature (Name) VALUES ('Is "+actors[m]+" in the movie.');");	
				st.close();	
				for(int i=1;i<=movieCount;i++){	
					String tmdbid=moviedbids[i-1];		
					Thread.sleep(500);		
					st = c.createStatement();
					ArrayList<String> cast=getCast(tmdbid);
					String isinMovie="false";
					if(cast.contains(actors[m]))
						isinMovie="true";
					st.executeUpdate("INSERT INTO data (MovieID, FeatureID, Value) VALUES ("+i+","+feature_id+","+isinMovie+");");	
					st.close();
				
				}
		}
		
		//insert is director of the movie
				for(int m=0;m<directors.length;m++){
					feature_id++;
					st = c.createStatement();
						st.executeUpdate("INSERT INTO feature (Name) VALUES ('Is "+directors[m]+" the director of the movie.');");	
						st.close();	
						for(int i=1;i<=movieCount;i++){	
							String tmdbid=moviedbids[i-1];		
							Thread.sleep(500);		
							st = c.createStatement();
							String dir=getDirector(tmdbid);
							String isinMovie="false";
							if(dir.equals(directors[m]))
								isinMovie="true";
							st.executeUpdate("INSERT INTO data (MovieID, FeatureID, Value) VALUES ("+i+","+feature_id+","+isinMovie+");");	
							st.close();
						
						}
				}
				
				//insert is genre of the movie
				for(int m=0;m<genres.length;m++){
					feature_id++;
					st = c.createStatement();
						st.executeUpdate("INSERT INTO feature (Name) VALUES ('Is the movie a"+genres[m]+".');");	
						st.close();	
						for(int i=1;i<=movieCount;i++){	
							String tmdbid=moviedbids[i-1];		
							Thread.sleep(500);		
							st = c.createStatement();
							ArrayList<String> gen=getMovieGenres(tmdbid);
							String isinMovie="false";
							if(gen.contains(genres[m]))
								isinMovie="true";
							st.executeUpdate("INSERT INTO data (MovieID, FeatureID, Value) VALUES ("+i+","+feature_id+","+isinMovie+");");	
							st.close();
						
						}
				}
				
				//insert is movie produced country
				for(int m=0;m<production_country.length;m++){
					feature_id++;
					st = c.createStatement();
						st.executeUpdate("INSERT INTO feature (Name) VALUES ('Is the movie produced in"+production_country[m]+ ".');");	
						st.close();	
						for(int i=1;i<=movieCount;i++){	
							String tmdbid=moviedbids[i-1];		
							Thread.sleep(500);		
							st = c.createStatement();
							ArrayList<String> count=getProductionCountries(tmdbid);
							String isinMovie="false";
							if(count.contains(production_country[m]))
								isinMovie="true";
							st.executeUpdate("INSERT INTO data (MovieID, FeatureID, Value) VALUES ("+i+","+feature_id+","+isinMovie+");");	
							st.close();
						
						}
				}
		
				//insert average vote
				feature_id++;
				st = c.createStatement();
				st.executeUpdate("INSERT INTO feature (Name) VALUES ('Average vote for the movie.');");	
				st.close();	
				for(int i=1;i<=movieCount;i++){	
				String tmdbid=getMovieDBID(i);		
				moviedbids[i-1]=tmdbid;
				Thread.sleep(500);		
				st = c.createStatement();
				String vote=getVoteAvg(tmdbid);
				st.executeUpdate("INSERT INTO data (MovieID, FeatureID, Value) VALUES ("+i+","+feature_id+","+vote+");");	
				st.close();
				}
				
				//insert budget
				feature_id++;
				st = c.createStatement();
				st.executeUpdate("INSERT INTO feature (Name) VALUES ('Budget for the movie.');");	
				st.close();	
				for(int i=1;i<=movieCount;i++){	
				String tmdbid=getMovieDBID(i);		
				moviedbids[i-1]=tmdbid;
				Thread.sleep(500);		
				st = c.createStatement();
				String budget=getMovieBudget(tmdbid);
				st.executeUpdate("INSERT INTO data (MovieID, FeatureID, Value) VALUES ("+i+","+feature_id+","+budget+");");	
				st.close();
				}
				
				//insert year
				feature_id++;
				st = c.createStatement();
				st.executeUpdate("INSERT INTO feature (Name) VALUES ('Year the movie was released.');");	
				st.close();	
				for(int i=1;i<=movieCount;i++){	
				String tmdbid=getMovieDBID(i);		
				moviedbids[i-1]=tmdbid;
				Thread.sleep(500);		
				st = c.createStatement();
				String release=getReleaseDate(tmdbid);
				st.executeUpdate("INSERT INTO data (MovieID, FeatureID, Value) VALUES ("+i+","+feature_id+","+release.substring(0, 4)+");");	
				st.close();
				}
				
		c.close();
		
	}
	catch(Exception exc){
		 System.err.println("Database error in inserting feature data. "+exc.toString());
	     System.exit(0);
	}
	
	
}


}
